\chapter{CRE2正则库应用案例}
本章根据\ref{intro-sec-regex-cases}节中整数有效性判断、电话号码有效性判断、
整数重复数字判断、找最亲近同学、比压牌和牌型分类6典型应用案例的需求，
使用CRE2正则库实现了正则表达式的编程。

\section{整数范围判断}
正整数字符串有效性判断的实现如代码\ref{code-int-range-cre2}所示。

\cvfile[label=code-int-range-cre2]{CRE2正则判断正整数范围有效性}%
  {google-cre2/codes/int-range/int-range-cre2.c}

在代码\ref{code-int-range-cre2}中，完成匹配后需要释放选项对象和正则对象占有的
内存空间。但该问题并不关注匹配的位置，因此，在54---55行的\cinline{cre2_match()} %
匹配函数调用中，为匹配寄存器数组传入了 \cinline{NULL} 指针和 \cinline{0} 长度。

\section{电话号码判断}
城市电话号码有效性判断的实现如代码\ref{code-phonenum-cre2}所示。

\cvfile[label=code-phonenum-cre2]{CRE2正则判断电话号码字符串有效性}%
  {google-cre2/codes/phonenum/phonenum-check-cre2.c}

在代码\ref{code-phonenum-cre2}中，第39行用\cinline{cre2_easy_match()} 函数直接
使用未编译的正则表达式实现了匹配。由于该问题并不关注匹配的位置，因此，
在39行的\cinline{cre2_easy_match()} 匹配函数调用中，为匹配寄存器数组传入了%
\cinline{NULL} 指针和 \cinline{0} 长度。

\section{判断重复数字}
判断整数中的重复数字的实现如代码\ref{code-repetition-cre2}所示。

\cvfile[label=code-repetition-cre2]{CRE2正则判断并显示重复数字}%
  {google-cre2/codes/repetitionnum/repetition-numb-cre2.c}

在代码\ref{code-repetition-cre2}中，第56行的正则表达式中不能分组反向引用，
因此，需要构造完整正则表达式。为实现重复匹配以检查所有重复数字，
使用\cinline{cre2_find_and_consume()} 查找与剔除匹配函数剔除匹配字符后，
实现字符串偏移，并为\cinline{cre2_find_and_consume()} 函数输入了匹配寄存器
数组首地址和长度。第61---70行的循环实现了重复匹配，并在循环中\cinline{flag}%
记录了是否有匹配发生的状态。

\section{寻找亲近同学}
寻找亲近同学的实现如代码\ref{code-findclosest-cre2}所示。

\cvfile[label=code-findclosest-cre2]{CRE2正则寻找亲近同学}%
  {google-cre2/codes/findclosest/findclosest-cre2.c}

在代码\ref{code-findclosest-cre2}中，第51---62行根据喜欢的类型动态构造需要的
正则表达式，注意需要添加一对小括号以实现对整体正则表达式的编号处理。为实现重复
匹配以检查所有喜欢的同学，使用\cinline{cre2_find_and_consume_re()} 查找与剔除
匹配函数剔除匹配字符后，实现字符串偏移，并为\cinline{cre2_find_and_consume_re()} %
函数传入了匹配寄存器数组首地址和长度。第81---91行的循环实现了重复匹配，并在循环%
中记录了匹配后的状态(第84---88行)。

\section{比压牌}
比压牌的实现如代码\ref{code-judgepoker-cre2}所示。

\cvfile[label=code-judgepoker-cre2]{CRE2正则判断比压牌}%
  {google-cre2/codes/judgepoker/judgepoker-cre2.c}

在代码\ref{code-judgepoker-cre2}中，第39---48行构造了正则表达式查找表。
第58---65行，根据对方出牌的张数，在正则表达式查找表中取得需要正则搜索的
正则表达式。第81---82行用\cinline{cre2_match()}函数实现了正则匹配。
由于该问题并不关注匹配的位置，因此，在第82行的\cinline{cre2_match()} 函数
调用中，为其匹配寄存器形参提供了指针为\cinline{NULL}，长度为0的实参。

\section{牌型分类}
牌型分类的实现如代码\ref{code-classifypoker-cre2}所示。

\cvfile[label=code-classifypoker-cre2]{CRE2正则牌型分类}
  {google-cre2/codes/classify-poker-5cards/classify-poker-5cards-cre2.c}

在代码\ref{code-classifypoker-cre2}中，第45---70行构造了正则表达式查找表，注意，
由于CRE2不支持分组的反向引用，因此需要构造完整正则表达式。
第79---104行通过遍历正则表达式查找表，通过正则搜索获得能够匹配的正则表达式下标索引。
由于该问题并不关注匹配的位置，因此，在第92---93行的\cinline{cre2_match()} 函数
调用中，为其匹配寄存器形参提供了指针为\cinline{NULL}，长度为0的实参。

当然，如果所有正则表达式都无法匹配，则返回循环结束后的\cinline{i}值(第86行)。
